还记得这道题的第一个版本吗?
当时为了给 @Mooophy 解释,我还列了个式子。假设 slow 和 fast 在走了x步后相遇,此刻:
由于相遇,所以 fast - slow = x+1 = 一圈的步长。假设进入圈需要 m 步。那么
咦,m+1 里面的 m 不就是从开始入圈所需要的步数吗?假设 head 从头开始走,让 slow 再走一步。
那么 m 步之后,head 和 slow 将同时到达圈的入口!!!
这个入口不就是返回值吗?
这道题真的是太奇妙了,我仅仅是稍稍改了一下第一版的程序,就 AC 了。
为了不破坏原来的链表,我用废弃的 fast 顶替了
head。
经 @Mooophy 点拨,这里的 head 其实是以传值的方式传入的,所以我不会破坏原来的链表,早上糊涂了。
直接使用 head ,代码更加的直观易懂,就像一场接力赛,head 觉得 slow 太慢了,从原点出发接力 slow.
不过,他并不知道,自己那速度,也赶不上 fast 啊,哈哈。
#include <cstddef>
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
if (head && head->next)
for (ListNode *slow = head, *fast = head->next; fast && fast->next; slow = slow->next, fast = fast->next->next)
if (slow == fast)
for (slow = slow->next; true; head = head->next, slow = slow->next)
if (slow == head) return slow;
return NULL;
}
};